﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Xml.Serialization;

namespace AnOtherBlog.Core
{
	/// <summary>
	/// Clase base de la que se derivan los objetos del negocio
	/// </summary>
	/// <typeparam name="TYPE">Tipo de la clase derivada</typeparam>
	/// <typeparam name="KEY">Tipo del identificador único de cada instancia</typeparam>
	public abstract class BlogBaseClass<TYPE, KEY> : IDisposable where TYPE : BlogBaseClass<TYPE, KEY>, new()
	{

		#region Destructor

		/// <summary>
		/// Destructor, invoques Dispose implementation 
		/// <remarks>
		/// De esta manera las clases derivadas no necesitan un destructor
		/// 
		/// IMPORTANTE: Se invoca el metodo Dispose con el argumento false
		/// se supone que se condificará con estructuras using( ... ) { ... }
		/// </remarks>
		/// </summary>
		~BlogBaseClass()
		{
			Dispose(false);
		}

		#endregion

		#region Fields and Properties

		private KEY _Id;
		/// <summary>
		/// Identificador único del objeto
		/// </summary>
		public KEY Id
		{
			get { return _Id; }
			set { _Id = value; }
		}

		private DateTime _DateCreated = DateTime.MinValue;
		/// <summary>
		/// Fecha de creación
		/// </summary>
		public DateTime DateCreated
		{
			get
			{
				return _DateCreated;
			}
			set
			{
				_DateCreated = value;
			}
		}

		private DateTime _DateModified = DateTime.MinValue;
		/// <summary>
		/// Fecha de modificación
		/// </summary>
		public DateTime DateModified
		{
			get
			{
				return _DateModified;
			}
			set
			{
				_DateModified = value;
			}
		}

		private bool _IsNew = true;
		/// <summary>
		/// Indica si el objeto es nuevo (no está en la base de datos)
		/// </summary>
		[XmlIgnore()]
		public bool IsNew
		{
			get
			{
				return _IsNew;
			}
			set
			{
				_IsNew = value;
			}
		}

		// TODO: Hay que pensar un mecanismo automático para ReLoad
		private bool _IsProxy = false;
		/// <summary>
		/// Indica si el objeto se cargó desde la base de datos en modo proxy
		/// </summary>
		[XmlIgnore()]
		public bool IsProxy
		{
			get
			{
				return _IsProxy;
			}
			set
			{
				_IsProxy = value;
			}
		}

		#endregion


		#region IDisposable Members

		/// <summary>
		/// Disposes the object and frees ressources for the Garbage Collector.
		/// </summary>
		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		/// <summary>
		/// Gets or sets if the object has been disposed.
		/// <remarks>
		/// If the objects is disposed, it must not be disposed a second time. 
		/// The _IsDisposed field is set the first time the object is disposed. If the IsDisposed property is true, then the Dispose()
		/// method will not dispose again. This help not to prolong the object's life if the Garbage Collector.
		/// </remarks>
		/// </summary>
		private bool _IsDisposed = false;

		/// <summary>
		/// Disposes de object and frees ressources for Gargabe Collector
		/// </summary>
		/// <remarks>
		/// Dispose(bool disposing) executes in two distinct scenarios.
		/// If disposing equals true, the method has been called directly or indirectly by a user's code. Managed and unmanaged resources
		/// can be disposed.
		/// If disposing equals false, the method has been called by the runtime from inside the finalizer and you should not reference 
		/// other objects. Only unmanaged resources can be disposed.
		/// </remarks>
		/// <param name="disposing">If true, the objects gets disposing</param>
		protected virtual void Dispose(bool disposing)
		{
			if (!_IsDisposed)
			{
				if (disposing)
				{
					// Aquí se trabaja con los recursos administrados estos son los que vamos a crear por cada instancia de la clase base
				}
				// Aquí se trabaja con los recursos no administrados
			}
			this._IsDisposed = true;
		}

		#endregion
	

	}
}
